import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(
      home: SignaturePainterPage(),
      debugShowCheckedModeBanner: false,
    ));

class SignaturePainterPage extends StatefulWidget {
  const SignaturePainterPage({super.key});

  @override
  _SignaturePainterPageState createState() => _SignaturePainterPageState();
}

class _SignaturePainterPageState extends State<SignaturePainterPage> {
  List<Offset?> _points = <Offset>[];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: GestureDetector(
          onPanStart: (DragStartDetails details) {
            Offset position = details.globalPosition;
            _points.add(position);
          },
          onPanUpdate: (DragUpdateDetails details) {
            setState(() {
              RenderBox object = context.findRenderObject() as RenderBox;
              Offset localPosition =
                  object.globalToLocal(details.globalPosition);
              _points = List.from(_points)..add(localPosition);
            });
          },
          onPanEnd: (DragEndDetails details) {
            _points.add(null);
          },
          child: CustomPaint(
            painter: SignaturePainter(points: _points),
            size: Size.infinite,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.clear),
        onPressed: () => _points.clear(),
      ),
    );
  }
}

class SignaturePainter extends CustomPainter {
  List<Offset?> points;

  SignaturePainter({required this.points});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = Colors.blue
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 10.0;

    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        canvas.drawLine(points[i]!, points[i + 1]!, paint);
      }
    }
  }

  @override
  bool shouldRepaint(SignaturePainter oldDelegate) =>
      oldDelegate.points != points;
}
